#include <func.h>

#define MAXPATH 1024
#define MAXBUF  4096

void cp_file(const char* src, const char* dst)
{
    // 1. 打开文件描述符
    int srcfd = open(src, O_RDONLY);
    if (srcfd == -1) {
        perror("open()");
        exit(1);
    }
    int dstfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (dstfd == -1) {
        perror("open()");
        exit(1);
    }
    // 2. 复制文件
    int n;
    char buf[MAXBUF];
    while ((n = read(srcfd, buf, MAXBUF)) > 0) {
        write(dstfd, buf, n);
    }
    // 3. 关闭文件描述符
    close(srcfd);
    close(dstfd);
}

void cp_dir(const char* src, const char* dst) {
    // src 是一个目录, dst 表示的目录不存在
    // 1. 创建 dst 目录
    mkdir(dst, 0777);
    // 2. 递归复制 src 里面的每一个目录项
    DIR* stream = opendir(src);
    if (!stream) {
        perror("opendir()");
        exit(1);
    }

    errno = 0;
    struct dirent* curr;
    while ((curr = readdir(stream)) != NULL) {
        // 忽略 . 和 ..
        char* filename = curr->d_name;
        if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) {
            continue;
        }
        // 拼接路径
        char subsrc[MAXPATH];
        char subdst[MAXPATH];
        sprintf(subsrc, "%s/%s", src, filename);
        sprintf(subdst, "%s/%s", dst, filename);

        if (curr->d_type == DT_DIR) {
            // 递归复制
            cp_dir(subsrc, subdst);
        } else if (curr->d_type == DT_REG) {
            cp_file(subsrc, subdst);
        }
    }  // curr == NULL
    if (errno) {
        perror("readdir()");
        exit(1);
    }
    closedir(stream);
}

int main(int argc, char* argv[])
{
    // ./cpDir src dst
    if (argc != 3) {
        fprintf(stderr, "Usage: %s src dst\n", argv[0]);
        exit(1);
    }

    cp_dir(argv[1], argv[2]);

    return 0;
}

